package com.xinQing.blogme.conf.security;

import lombok.Setter;
import org.springframework.security.authentication.AccountExpiredException;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.CredentialsExpiredException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;

/**
 * JWT认证管理
 *
 * Created by null on 2017/8/2.
 */

@Setter
public class JWTAuthenticationProvider implements AuthenticationProvider {

    private UserDetailsService userDetailsService;

    private PasswordEncoder passwordEncoder;

    /**
     * 重写身份认证
     *
     * @param authentication 用户登录时的信息
     * @return Authentication  身份认证信息
     * @throws AuthenticationException 身份认证异常
     */
    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        UsernamePasswordAuthenticationToken token = (UsernamePasswordAuthenticationToken) authentication;
        // 用户名
        String username = token.getName();
        //  导入UserDetails，判断账号是否有效，为null说明查询不到用户，账号不存在
        UserDetails userDetails = userDetailsService.loadUserByUsername(username);
        if (userDetails == null) {
            throw new UsernameNotFoundException("账号不存在");
        }

        if (!userDetails.isEnabled()) {
            throw new DisabledException("账号已被禁用");
        } else if (!userDetails.isAccountNonExpired()) {
            throw new AccountExpiredException("账号已过期");
        } else if (!userDetails.isCredentialsNonExpired()) {
            throw new CredentialsExpiredException("凭证已过期");
        }
        /*------------------------------------------------------------
         *       判断账号是否能正确使用 结束
         *-----------------------------------------------------------*/

        /*------------------------------------------------------------
         *       验证密码是否正确 开始
         *-----------------------------------------------------------*/
        //  数据库用户的密码(已经加密)
        String password = userDetails.getPassword();
        //  与authentication里面的credentials相比较，加密在这里体现
//        if (!passwordEncoder.matches(token.getCredentials().toString(), password)) {
//            throw new BadCredentialsException("密码错误");
//        }
        if (!token.getCredentials().toString().equals(password)) {
            throw new BadCredentialsException("密码错误");
        }
        /*------------------------------------------------------------
         *       验证密码是否正确 结束
         *-----------------------------------------------------------*/

        return new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities());
    }

    @Override
    public boolean supports(Class<?> authentication) {
        //  返回true后才会执行上面的authenticate方法，这步能确保authentication能正确转换类型
        return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }
}
